package at.fhhagenberg.hydrac;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * CLIMain
 * 
 * @author Richard Reiffinger, Johannes Karder
 */
public class CLIMain {

  /**
   * @param args
   */
  public static void main(String[] args) {
    // No Parameters
    if (args.length == 0) {
      halt("No Parameters found!");
    }
    // --help
    if (equalParams(args[0], "--help") || equalParams(args[0], "-h") || equalParams(args[0], "/?")) {
      showHelp(true);
    }
    // --version
    if (equalParams(args[0], "--version")) {
      showVersion(true);
    }

    // Not enough Parameters
    if (args.length < 2) { // 2 => Output Format + Input File
      halt("Not enough Parameters!");
    }

    // Determine options
    Level logLevel = Level.WARNING;
    boolean pascalOutput = false;
    boolean javaOutput = false;
    boolean astOutput = false;
    final List<String> inputFiles = new ArrayList<>();
    int i = 0;
    for (; i < args.length; i++) {
      // --debug
      if (equalParams(args[i], "--debug")) {
        logLevel = Level.ALL;
        continue;
      }
      // -Pascal
      if (equalParams(args[i], "-PAS")) {
        pascalOutput = true;
        continue;
      }
      // -JAVA
      if (equalParams(args[i], "-JAVA")) {
        javaOutput = true;
        continue;
      }
      // -AST
      if (equalParams(args[i], "-AST")) {
        astOutput = true;
        continue;
      }
      // InputFile
      if (new File(args[i]).exists()) {
        inputFiles.add(args[i]);
        continue;
      }
      // Unknown Parameter
      halt("Unknown Parameter or File: " + args[i]);
    } // for

    // Initialize Logging
    final Handler handler = new ConsoleOutputHandler();
    handler.setLevel(logLevel);
    final Logger logger = Logger.getLogger("HydraC");
    logger.setLevel(logLevel);
    logger.addHandler(handler);

    // Run selected Compilers
    if (pascalOutput) {
      initCompiler(new PascalCompiler(logger), inputFiles);
    }
    if (javaOutput) {
      initCompiler(new JavaCompiler(logger), inputFiles);
    }
    if (astOutput) {
      initCompiler(new AstCompiler(logger), inputFiles);
    }
  }

  // Print Error and stop Application with Error Code 1
  private static void halt(String message) {
    System.err.println("Error: " + message);
    System.exit(1);
  }

  // Determines if two parameters are equal
  private static boolean equalParams(String param1, String param2) {
    return param1.toLowerCase().equals(param2.toLowerCase());
  }

  // Prints Help Summary
  private static void showHelp(boolean exit) {
    showVersion(false);
    System.out.println(
        "--help -h /? \t\t\tShow this help.\n" +
            "--debug\t\t\tPrints Debug Information\n" +
            "-JAVA\t\t\tCreates a Java Source File\n" +
            "-AST\t\t\tCreates an AST Represenation File\n" +
            "-PAS\t\t\tCreates a PASCAL Source File\n");
    if (exit) {
      System.exit(0);
    }
  }

  // Prints Program Version Information
  private static void showVersion(boolean exit) {
    System.out.println("HydraC - Pseudocode Crosscompiler [Version 1.0]");
    if (exit) {
      System.exit(0);
    }
  }

  // Initializes a Compiling Process and Logging Handler
  private static void initCompiler(Compiler c, List<String> inputFiles) {
    for (final String fileName : inputFiles) {
      c.compile(fileName);
    }
  }

} // class
